package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.FindServer;
/**
 * A client class which can connect to the server.
 * 
 * @author benjamin
 */
public class Client implements Runnable {
    private String name;                        // client name
    private String host;                        // host IP v4 address
    private int port;                           // port number
    private Deque<String> messageQueue = null;  // message queue
    private Boolean isAlive = true;             // is 'alive'?
    private Socket socket;                      // 
    private PrintWriter serverOut;
    private BufferedReader serverIn;
    
    public String getName() {
        return name;
    }
    
    public String getMessage() {
        return messageQueue.poll();
    }
    
    public void addMessage(String msg) {
        messageQueue.add(msg);
    }
    
    /**
     * Kill the client
     */
    public void kill() {
        isAlive = false;
    }
    
    public Client(String _name, String _host, int _port) {
        name = _name;
        host = _host;
        port = _port;
    }
    
    public boolean connect() {
        boolean isAlive = false;
        messageQueue = new ArrayDeque<>();
        try {
            isAlive = FindServer.isAlive(InetAddress.getByName(host), port, 1000);
            if(isAlive) {
                addMessage("Trying to connect to the server @ " + host + ":" + port);
                socket = new Socket(host, port);
                serverOut = new PrintWriter(socket.getOutputStream(), true);
                serverIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                addMessage("Connection established!");
            }
        } catch (UnknownHostException ex) {
            addMessage("Unknown host @ " + name + ":" + port);
        }
        catch (IOException e) {
            addMessage("Couldn't connect to host @ " + name + ":" + port);
        }
        finally {
            return isAlive;
        }
    }
    
    public void disconnect() {
        try {
            kill();
            this.serverIn.close();
            this.serverOut.close();
            this.socket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
    /**
     * Send data to the server
     * @param msg 
     */
    public void sendData(String msg) {
        serverOut.println(msg);
    }

    @Override
    public void run() {
        performHandshake(); //Send some initial data to the server.
        // Receive input from the client and send it to the server while alive.
        while(isAlive) {
            String data = null;
            try {
                //Data from the server
                data = serverIn.readLine();
            } catch (IOException ex) {
                
            }
            if(data != null) {
                //Append the data to the message queue
                addMessage(data);
            }
        }
    }

    /**
     * Send some data to the server on connect.
     * Put all commands / messages here.
     */
    private void performHandshake() {
        sendData("/nick " + name);
    }
    
}
